package com.verykim.video;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Text;

@SuppressWarnings("serial")
public class AdminServlet extends HttpServlet {

	final String enc = "utf-8";

	@Override
	public void doGet(final HttpServletRequest req,
			final HttpServletResponse resp) throws IOException {

		// BackendService backendsApi =
		// BackendServiceFactory.getBackendService();
		// Get the backend handling the current request.
		// String currentBackendName = backendsApi.getCurrentBackend();
		// Get the backend instance handling the current request.
		// int currentInstance = backendsApi.getCurrentInstance();

		resp.setContentType("text/html");
		resp.setCharacterEncoding(enc);
		resp.addHeader("Cache-Control", "no-cache");
		final String type = req.getParameter("type");
		if (null == type) {
			return;
		}
		if (type.equals("VideoDelete")) {
			final String title = req.getParameter("title");
			final String category = req.getParameter("category");
			if (null == title || null == category) {
				return;
			}
			resp.getWriter().print(Video.delete(category, title));
		} else if (type.equals("VideoEdit")) {
			final String title = req.getParameter("title");
			final String category = req.getParameter("category");
			if (null == title || null == category) {
				return;
			}
			final Entity E = Video.video(category, title);
			if (null == E) {
				return;
			}
			final StringBuilder js_code = new StringBuilder();
			js_code.append("category = \"" + category + "\";\n");
			js_code.append("title = \"" + title + "\";\n");
			final Object AREA = E.getProperty(Video.P_AREA);
			if (null != AREA) {
				js_code.append("area = \"" + AREA.toString() + "\";\n");
			}
			final Object PERIOD = E.getProperty(Video.P_PERIOD);
			if (null != PERIOD) {
				js_code.append("period = \"" + PERIOD.toString() + "\";\n");
			}
			final Object DIRECTOR = E.getProperty(Video.P_DIRECTOR);
			if (null != DIRECTOR) {
				js_code.append("director = \"" + DIRECTOR.toString() + "\";\n");
			}
			final Object BLOBKEY = E.getProperty(Video.UP_BLOBKEY);
			if (null != BLOBKEY) {
				js_code.append("blobKey = \""
						+ ((BlobKey) BLOBKEY).getKeyString() + "\";\n");
			}
			final Object SUMMARY = E.getProperty(Video.UP_SUMMARY);
			final Object CONTENT = E.getProperty(Video.UP_CONTENT);

			@SuppressWarnings("unchecked")
			final List<String> actors = (List<String>) E
					.getProperty(Video.P_ACTORS);
			if (actors != null && !actors.isEmpty()) {
				js_code.append("actors_arr = new Array();\n");
				for (final String a : actors) {
					js_code.append("actors_arr.push(\""
							+ a.replaceAll("\\n|\\r", "") + "\");\n");
				}
			}
			@SuppressWarnings("unchecked")
			final List<String> qvod = (List<String>) E
					.getProperty(Video.UP_QVOD);
			if (qvod != null && !qvod.isEmpty()) {
				js_code.append("qvod_arr = new Array();\n");
				for (final String q : qvod) {
					if (q.startsWith("qvod://")) {
						js_code.append("qvod_arr.push(\""
								+ q.replaceAll("\\s|\\n|\\r", "") + "\");\n");
					}
				}
			}
			@SuppressWarnings("unchecked")
			final List<String> bdhd = (List<String>) E
					.getProperty(Video.UP_BDHD);
			if (bdhd != null && !bdhd.isEmpty()) {
				js_code.append("bdhd_arr = new Array();\n");
				for (final String b : bdhd) {
					if (b.startsWith("bdhd://")) {
						js_code.append("bdhd_arr.push(\""
								+ b.replaceAll("\\s|\\n|\\r", "") + "\");\n");
					}
				}
			}
			@SuppressWarnings("unchecked")
			final List<String> ed2k = (List<String>) E
					.getProperty(Video.UP_ED2K);
			if (ed2k != null && !ed2k.isEmpty()) {
				js_code.append("ed2k_arr = new Array();\n");
				for (final String e : ed2k) {
					if (e.startsWith("ed2k://")) {
						js_code.append("ed2k_arr.push(\""
								+ e.replaceAll("\\s|\\n|\\r", "") + "\");\n");
					}
				}
			}
			final String html = getHtml("admin.html")
					.replace("/*##server_code##*/", js_code.toString())
					.replace("##summary##", SUMMARY.toString())
					.replace("##content##", ((Text) CONTENT).getValue());
			resp.getWriter().print(html);
		} else if (type.equals("UploadUrl")) {
			final BlobstoreService bs = BlobstoreServiceFactory
					.getBlobstoreService();
			resp.getWriter().print(bs.createUploadUrl("/admin.do"));
		} else if (type.equals("CronVideosKeys")) {
			final String key = "all-videos-title";

			final Entity kv = KeyValue.get(key);

			final Iterator<Entity> Ikeys = Video
					.KeysOnlyVideos(null == kv ? true : false);

			@SuppressWarnings("unchecked")
			final List<Key> OldVideoKeys = null == kv ? new ArrayList<Key>()
					: (List<Key>) kv.getProperty(KeyValue.UP_VALUE);

			if (Ikeys != null) {
				final List<Key> VideoKeys = new ArrayList<Key>();
				while (Ikeys.hasNext()) {
					final Entity E = Ikeys.next();
					VideoKeys.add(E.getKey());
				}
				if (!VideoKeys.isEmpty()) {
					if (!OldVideoKeys.isEmpty()) {
						OldVideoKeys.addAll(VideoKeys);
						final HashSet<Key> hs = new HashSet<Key>(OldVideoKeys);
						OldVideoKeys.clear();
						OldVideoKeys.addAll(hs);
					} else {
						OldVideoKeys.addAll(VideoKeys);
					}
					final KeyValue new_kv = new KeyValue(key, OldVideoKeys);
					if (KeyValue.put(new_kv)) {

						resp.getWriter()
								.print("ok<br />" + OldVideoKeys.size());
					}
				}
			}

		} else {

		}
	}

	@Override
	public void doPost(final HttpServletRequest req,
			final HttpServletResponse resp) throws IOException {
		// req.setCharacterEncoding(enc);
		final String req_enc = req.getCharacterEncoding();
		resp.setContentType("text/html");
		resp.setCharacterEncoding(enc);
		resp.addHeader("Cache-Control", "no-cache");
		try {

			final String category = req.getParameter("category");
			final String title = req.getParameter("title");
			if (null == title) {
				return;
			}

			final String period = req.getParameter("period");
			final String area = req.getParameter("area");
			final String director = req.getParameter("director");
			final String summary = req.getParameter("summary");
			final String content = req.getParameter("content");

			String[] actors;

			final String _actors = req.getParameter("actors");
			if (_actors.contains(",")) {
				actors = _actors.split("\\,");
			} else {
				actors = req.getParameterValues("actors");
			}

			final String[] qvod = req.getParameterValues("qvod");
			final String[] bdhd = req.getParameterValues("bdhd");
			final String[] ed2k = req.getParameterValues("ed2k");

			final String blobKeyString = req.getParameter("blobKey");

			final Video video = new Video(category);
			video.Title(title);
			video.Period(Integer.parseInt(period));
			video.Area(area);
			if (null != director) {
				video.Director(director);
			}
			if (null != actors) {
				video.Actors(actors);
			}
			video.Qvod(qvod);
			video.Bdhd(bdhd);
			video.Ed2k(ed2k);
			video.Summary(summary);
			video.Content(content);

			if (req.getContentType().startsWith("multipart/form-data")) {
				final BlobstoreService bs = BlobstoreServiceFactory
						.getBlobstoreService();
				if (null != blobKeyString) {
					final BlobKey blobKey = new BlobKey(blobKeyString);
					if (null != blobKey) {
						bs.delete(blobKey);
					}
				}
				final Map<String, List<BlobKey>> blobs = bs.getUploads(req);
				final BlobKey _blobKey = blobs.get("theFile").iterator().next();
				if (null != _blobKey) {
					video.Blobkey(_blobKey);
				}
			} else {
				video.Blobkey(new BlobKey(blobKeyString));
			}

			if (Video.add(video)) {
				resp.getWriter().print(title + " - " + req_enc);
			} else {
				resp.getWriter().print("no");
			}
		} catch (Exception e) {
			resp.getWriter().print(e.getMessage());
		}
	}

	String getHtml(final String fileName) {
		final StringBuilder sb = new StringBuilder();
		try {
			int flag = -1;
			final FileInputStream fis = new FileInputStream(fileName);
			final InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
			while ((flag = isr.read()) != -1) {
				sb.append((char) flag);
			}
		} catch (FileNotFoundException e) {
			sb.append(e.getMessage());
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sb.toString();
	}
}
